// script.aculo.us builder.js v1.7.0, Fri Jan 19 19:16:36 CET 2007

// Copyright (c) 2005, 2006 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/


var Builder = {
  NODEMAP: {
	AREA: 'map',
	CAPTION: 'table',
	COL: 'table',
	COLGROUP: 'table',
	LEGEND: 'fieldset',
	OPTGROUP: 'select',
	OPTION: 'select',
	PARAM: 'object',
	TBODY: 'table',
	TD: 'table',
	TFOOT: 'table',
	TH: 'table',
	THEAD: 'table',
	TR: 'table'
  },
  // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
  //       due to a Firefox bug
  node: function(elementName) {
	elementName = elementName.toUpperCase();

	// try innerHTML approach
	var parentTag = this.NODEMAP[elementName] || 'div';
	var parentElement = document.createElement(parentTag);
	try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
	  parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
	} catch(e) {}
	var element = parentElement.firstChild || null;

	// see if browser added wrapping tags
	if(element && (element.tagName.toUpperCase() != elementName))
	  element = element.getElementsByTagName(elementName)[0];

	// fallback to createElement approach
	if(!element) element = document.createElement(elementName);

	// abort if nothing could be created
	if(!element) return;

	// attributes (or text)
	if(arguments[1])
	  if(this._isStringOrNumber(arguments[1]) ||
		(arguments[1] instanceof Array)) {
		  this._children(element, arguments[1]);
		} else {
		  var attrs = this._attributes(arguments[1]);
		  if(attrs.length) {
			try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
			  parentElement.innerHTML = "<" +elementName + " " +
				attrs + "></" + elementName + ">";
			} catch(e) {}
			element = parentElement.firstChild || null;
			// workaround firefox 1.0.X bug
			if(!element) {
			  element = document.createElement(elementName);
			  for(attr in arguments[1])
				element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
			}
			if(element.tagName.toUpperCase() != elementName)
			  element = parentElement.getElementsByTagName(elementName)[0];
			}
		}

	// text, or array of children
	if(arguments[2])
	  this._children(element, arguments[2]);

	 return element;
  },
  _text: function(text) {
	 return document.createTextNode(text);
  },

  ATTR_MAP: {
	'className': 'class',
	'htmlFor': 'for'
  },

  _attributes: function(attributes) {
	var attrs = [];
	for(attribute in attributes)
	  attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
		  '="' + attributes[attribute].toString().escapeHTML() + '"');
	return attrs.join(" ");
  },
  _children: function(element, children) {
	if(typeof children=='object') { // array can hold nodes and text
	  children.flatten().each( function(e) {
		if(typeof e=='object')
		  element.appendChild(e)
		else
		  if(Builder._isStringOrNumber(e))
			element.appendChild(Builder._text(e));
	  });
	} else
	  if(Builder._isStringOrNumber(children))
		 element.appendChild(Builder._text(children));
  },
  _isStringOrNumber: function(param) {
	return(typeof param=='string' || typeof param=='number');
  },
  build: function(html) {
	var element = this.node('div');
	$(element).update(html.strip());
	return element.down();
  },
  dump: function(scope) {
	if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope

	var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
	  "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
	  "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
	  "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
	  "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
	  "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);

	tags.each( function(tag){
	  scope[tag] = function() {
		return Builder.node.apply(Builder, [tag].concat($A(arguments)));
	  }
	});
  }
}
